package cn.yzj.openapi.service.impl;

import cn.yzj.http.YzjHttp;
import cn.yzj.http.YzjHttpResult;
import cn.yzj.http.YzjSendConfig;
import cn.yzj.openapi.basic.WebBasicAuthRequest;
import cn.yzj.openapi.bo.SignSettingsBO;
import cn.yzj.openapi.dao.intf.ApiSettingsDao;
import cn.yzj.openapi.dao.intf.TiebaSignDao;
import cn.yzj.openapi.dto.EmailDTO;
import cn.yzj.openapi.entity.ApiSettingsEntity;
import cn.yzj.openapi.service.EmailService;
import cn.yzj.openapi.service.SignService;
import cn.yzj.utils.JsonUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.cache.Cache;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 签到服务
 *
 * @author gzkemays
 * @since 2022/5/1 20:28
 */
@Service
@Slf4j
public class SignServiceImpl implements SignService {
  @Resource TiebaSignDao tiebaSignDao;
  @Resource EmailService emailService;

  @Resource ApiSettingsDao settingsDao;

  @Resource(name = "sfCache")
  Cache<String, String> sfCache;

  final Pattern DOC_JSON_PATTERN = Pattern.compile("\\{([^}]*)}");

  @Override
  public void tiebaSign() {
    tiebaSignDao.sign();
  }

  @Override
  public void fuliSign() {
    ApiSettingsEntity sign = settingsDao.selectById("SIGN_FULI");
    List<SignSettingsBO> signSettingsBOS = SignSettingsBO.buildList(sign);
    for (SignSettingsBO signSettingsBO : signSettingsBOS) {
      // 签到的主页
      if (signSettingsBO.isSign()) {
        String baseUrl = signSettingsBO.getBaseUrl();
        FuliBasicUrls fuliBasicUrls = new FuliBasicUrls(baseUrl);
        log.info("{} 开始签到", baseUrl);
        WebBasicAuthRequest auth = login(signSettingsBO);
        Map<String, String> headers = getHeaders(auth, fuliBasicUrls);
        log.info("header -> {}", headers);
        if (xiaoAiSheMsgRefresh(headers, fuliBasicUrls)) {
          YzjHttpResult send =
              YzjHttp.createPost(fuliBasicUrls.getUserMissionUrl())
                  .headers(headers)
                  .defaultUserAgent()
                  .send();
          String result = send.getResult();
          log.info("{} Sign = {}", baseUrl, result);
          if (!JsonUtils.isJson(result)
              || "jwt_auth_invalid_token".equals(JSONObject.parseObject(result).get("code"))) {
            emailService.send(
                EmailDTO.builder()
                    .to("1538211287@qq.com")
                    .subject("open api 服务签到异常")
                    .message(new Date() + baseUrl + "签到失败,请求返回信息为:" + result)
                    .build());
          }
        }
      }
    }
  }

  @Override
  public void sfSign() {
    String url = "https://www.jiaosf.com/plugin.php";
    String cookie = sfCache.getIfPresent("cookie");
    ApiSettingsEntity sign_sf = settingsDao.selectById("SIGN_SF");
    String settings = sign_sf.getSettings();
    JSONObject jsonObject = JSONObject.parseObject(settings);
    JSONObject jiaosf = (JSONObject) jsonObject.get("jiaosf");
    if ((Boolean) jiaosf.get("sign")) {
      if (StringUtils.isNotBlank(cookie)) {
        // 如果 cookie 存在
        String formHash = getSfFormHash(cookie);
        if (formHash != null) {
          Map<String, String> headers = new HashMap<>();
          Map<String, Object> data = new HashMap<>();
          headers.put("referer", "https://www.jiaosf.com/");
          headers.put("Cookie", cookie);
          headers.put("Accept", "*/*");
          data.put("id", "k_misign:sign");
          data.put("operation", "qiandao");
          data.put("format", "button");
          data.put("formhash", formHash);
          data.put("inajax", 1);
          data.put("ajaxtarget", "midaben_sign");
          YzjHttpResult send =
              YzjHttp.createGet(url).defaultUserAgent().headers(headers).dataMap(data).send();
          String result = send.getResult();
          log.info("私服签到结果 -> {}", result);
          if (result.contains("非法")) {
            emailService.send(
                EmailDTO.builder()
                    .to("1538211287@qq.com")
                    .subject("私服网站签到异常")
                    .message(result)
                    .build());
          }
        }
      } else {
        emailService.send(
            EmailDTO.builder()
                .to("1538211287@qq.com")
                .subject("私服网站签到异常")
                .message("cookie 不存在")
                .build());
      }
    } else {
      System.out.println("停止签到");
    }
  }

  private String getSfFormHash(String cookie) {
    String url = "https://www.jiaosf.com/";
    YzjHttpResult send =
        YzjHttp.createGet(url)
            .defaultUserAgent()
            .cookies(cookie)
            .config(YzjSendConfig.start().document().end())
            .send();
    Document document = send.getDocument();
    Elements form = document.getElementsByTag("form");
    if (!form.isEmpty()) {
      Element element = form.get(0);
      Elements children = element.children();
      for (Element child : children) {
        if (child.attr("name").equals("formhash")) {
          return child.attr("value");
        }
      }
    }
    return null;
  }

  public WebBasicAuthRequest login(SignSettingsBO bo) {
    WebBasicAuthRequest webBasicAuthRequest = new WebBasicAuthRequest();
    String prefix = bo.getBaseUrl();
    String tmpToken = FULI_TEMP_TOKEN_URL.replace(PREFIX, prefix);
    String login = FULI_TOKEN_URL.replace(PREFIX, prefix);
    YzjHttpResult send = YzjHttp.createPost(tmpToken).defaultUserAgent().send();
    String result = send.getResult();
    Matcher m = DOC_JSON_PATTERN.matcher(result);
    if (m.find()) {
      String json = m.group();
      String token = JSON.parseObject(json).getString("token");
      Map<String, Object> map = new HashMap<>(3);
      map.put("username", bo.getUsername());
      map.put("password", bo.getPassword());
      map.put("token", token);
      YzjHttpResult loginSend =
          YzjHttp.createPost(login)
              .defaultUserAgent()
              .dataMap(map)
              .config(YzjSendConfig.start().cookie().postJson().end())
              .send();
      String cookie = loginSend.getCookie();
      int first = cookie.indexOf(";");
      webBasicAuthRequest.setToken(cookie.substring(0, first).replace("b2_token=", "Bearer "));
      webBasicAuthRequest.setCookie(cookie);
    }
    return webBasicAuthRequest;
  }

  private boolean xiaoAiSheMsgRefresh(Map<String, String> headers, FuliBasicUrls urls) {
    log.info("刷新 msg 判断是否有签到");
    Map<String, Object> data = new HashMap<>();
    // 发送 userMission 请求刷新用户的资料
    data.put("count", 3);
    data.put("paged", 1);
    YzjHttp.createPost(urls.getUserMissionUrlGet())
        .headers(headers)
        .dataMap(data)
        .defaultUserAgent()
        .send();
    // 获取 newDmsg 获取新的信息
    YzjHttpResult newDmsgResult =
        YzjHttp.createPost(urls.getNewUserMsgUrl()).headers(headers).defaultUserAgent().send();
    if (JsonUtils.isJson(newDmsgResult.getResult())) {
      // 判断是否刷新成功
      YzjHttpResult send =
          YzjHttp.createPost(urls.getRefreshUrl()).headers(headers).defaultUserAgent().send();
      String result = send.getResult();
      log.info("refresh msg = {}", result);
      if (JsonUtils.isJson(result)) {
        JSONObject json = JSONObject.parseObject(result);
        JSONObject task = json.getJSONObject("task");
        int finish =
            Optional.ofNullable(task.getJSONObject("task_mission").get("finish"))
                .map(i -> (int) i)
                .orElse(1);
        if (finish == 1) {
          emailService.send(
              EmailDTO.builder()
                  .to("1538211287@qq.com")
                  .subject("open api 服务签到异常")
                  .message(new Date() + "-" + urls.getBaseUrl() + "refresh 刷新后，签到记录为已签到")
                  .build());
        }
        return finish != 1;
      }
      return JsonUtils.isJson(send.getResult());
    }
    return false;
  }

  public static void main(String[] args) {
    SignServiceImpl signService = new SignServiceImpl();
    String sfFormHash =
        signService.getSfFormHash(
            "Hm_lvt_b755d2bffc75fda64e277513a4498c4f=1659578208,1659948082,1660008469; PHPSESSID=bqk6ff9ohbofohpa9tpc1rffs5; oz1H_2132_sid=rc88v3; oz1H_2132_lastvisit=1660005802; oz1H_2132_saltkey=f4zA9YaR; oz1H_2132_noticeTitle=1; oz1H_2132_sendmail=1; oz1H_2132_seccodecSAou7rc88v3=3969.6589f02327bc5b3a28; oz1H_2132_ulastactivity=e13cSnbILCqL1j0yeVED5OrsmjjKzg6evLAtLQuUmxq8ErXfIaRk; oz1H_2132_auth=9fdamHu9IO34cIWVNXDo0PjRH2cEBChG4qnxfaD25qboFOmekJ3KVeUmTqmUr49Z6Ux%2FDTlnPP0FoCz7V5y2jbm6nQ; oz1H_2132_lastcheckfeed=40110%7C1660009415; oz1H_2132_lip=183.22.33.207%2C1660008574; oz1H_2132_connect_is_bind=0; oz1H_2132_nofavfid=1; oz1H_2132_onlineusernum=457; oz1H_2132_checkpm=1; oz1H_2132_lastact=1660009579%09plugin.php%09; Hm_lpvt_b755d2bffc75fda64e277513a4498c4f=1660009582");
    System.out.println(sfFormHash);
  }
}
